//
//  Camera+Api.swift
//  WatermarkCamera
//
//  Created by AxcLogo on 4/7/2024.
//

import UIKit
import Foundation
import AxcBedrock

extension Camera {
    /// 闪光灯模式
    enum FlashMode: Int, CaseIterable {
        // 关闭

        case off = 0

        // 自适应

        case auto = 1

        // 开启

        case on = 2

        // 手电筒

        case torch = 3
    }

    /// 相机设备
    enum Position: Int {
        case unknown, back, front
    }
}

// MARK: - [CameraApi]

// 这里为了api阅读美观，采用了使用协议来代替OC开发模式中的.h文件
// 提高阅读和查找性

protocol CameraApi {
    /// 开始采集
    func beginCapture()

    /// 停止采集
    func endCapture()

    /// 暂停采集
    func pauseCapture()

    /// 重新采集
    func resumeCapture()

    /// 是否正在运行
    func isRunning() -> Bool

    /// 获取采集会话
    func captureSession() -> AVCaptureSession

    /// 设置采集清晰度
    func setCaptureArticulation(_ articulation: AVCaptureSession.Preset)

    /// 获取采集清晰度
    func captureArticulation() -> AVCaptureSession.Preset

    /// 设置输出图片朝向
    /// - Parameter outputImageOrientation: 朝向
    func setOutputImageOrientation(_ outputImageOrientation: UIInterfaceOrientation)

    /// 获取输出图片朝向
    func outputImageOrientation() -> UIInterfaceOrientation

    /// 设置前置水平镜像
    /// - Parameter horizontallyMirror: 水平镜像
    func setHorizontallyFrontMirror(_ isMirror: Bool)

    /// 获取是否开启前置水平镜像
    func horizontallyFrontMirror() -> Bool

    /// 设置后置水平镜像
    /// - Parameter horizontallyMirror: 水平镜像
    func setHorizontallyBackMirror(_ isMirror: Bool)

    /// 获取是否开启后置水平镜像
    func horizontallyBackMirror() -> Bool

    /// 设置前后相机
    /// - Parameter position: 位置前后
    func setPosition(_ position: Camera.Position)

    /// 获取当前前后相机
    func position() -> Camera.Position

    /// 翻转相机
    func rotateCamera()

    /// 摄像头即将切换
    func setWillRotateCameraBlock(_ block: @escaping AxcBlock.OneParam<Camera.Position>)

    /// 摄像头已经完成切换
    func setDidRotateCameraBlock(_ block: @escaping AxcBlock.OneParam<Camera.Position>)

    /// 设置缩放长焦短焦
    /// - Parameter factor: 缩放指数
    func setZoomFactor(_ factor: CGFloat)

    /// 获取缩放指数
    func zoomFactor() -> CGFloat

    /// 设置对焦点位
    /// - Parameter focusPoint: 对焦点，x，y取值0-1
    func setFoucsPoint(_ focusPoint: CGPoint)

    /// 设置连续自动对焦
    func setContinuousAutoFocus()

    /// 设置闪光灯模式
    /// - Parameter flashMode: 模式
    func setFlashMode(_ flashMode: Camera.FlashMode)

    /// 是否有手电筒功能
    func hasTorch() -> Bool

    /// 是否有闪光灯功能
    func hasFlash() -> Bool

    /// 采集照片
    /// - Parameters:
    ///   - gpuFilter: 输入节点
    ///   - block: 回调
    func collectPhoto(gpuFilter: GPUFilter,

                      block: @escaping AxcBlock.OneParam<UIImage>)
}

// MARK: - Camera + CameraApi

extension Camera: CameraApi {
    /// 开始采集
    func beginCapture() {
        gpuCamera.startCapture()
    }

    /// 停止采集
    func endCapture() {
        gpuCamera.stopCapture()
    }

    /// 暂停采集
    func pauseCapture() {
        gpuCamera.pauseCapture()
    }

    /// 重新采集
    func resumeCapture() {
        gpuCamera.resumeCameraCapture()
    }

    /// 是否正在运行
    func isRunning() -> Bool {
        return gpuCamera.isRunning
    }

    /// 采集会话
    func captureSession() -> AVCaptureSession {
        return gpuCamera.captureSession
    }

    /// 设置采集清晰度
    func setCaptureArticulation(_ articulation: AVCaptureSession.Preset) {
        gpuCamera.captureSession?.axc.configuration { [weak self] in

            guard let weakSelf = self else { return }

            if weakSelf.gpuCamera.captureSession.canSetSessionPreset(articulation) {
                weakSelf.gpuCamera.captureSession.sessionPreset = articulation
            }
        }
    }

    /// 获取采集清晰度
    func captureArticulation() -> AVCaptureSession.Preset {
        return gpuCamera.captureSession.sessionPreset
    }

    /// 设置输出图片朝向
    func setOutputImageOrientation(_ outputImageOrientation: UIInterfaceOrientation) {
        gpuCamera.outputImageOrientation = outputImageOrientation
    }

    /// 获取输出图片朝向
    func outputImageOrientation() -> UIInterfaceOrientation {
        return gpuCamera.outputImageOrientation
    }

    /// 设置前置水平镜像
    func setHorizontallyFrontMirror(_ isMirror: Bool) {
        gpuCamera.horizontallyMirrorFrontFacingCamera = isMirror
    }

    /// 获取前置水平镜像
    func horizontallyFrontMirror() -> Bool {
        return gpuCamera.horizontallyMirrorFrontFacingCamera
    }

    /// 设置后置水平镜像
    func setHorizontallyBackMirror(_ isMirror: Bool) {
        gpuCamera.horizontallyMirrorRearFacingCamera = isMirror
    }

    /// 获取后置水平镜像
    func horizontallyBackMirror() -> Bool {
        return gpuCamera.horizontallyMirrorRearFacingCamera
    }

    /// 设置前后相机
    func setPosition(_ position: Camera.Position) {
        switch gpuCamera.cameraPosition() {
        case .back: // 后置切换前置

            switch position {
            case .front: rotateCamera()

            default: break
            }

        case .front: // 前置切换后置

            switch position {
            case .back: rotateCamera()

            default: break
            }

        default: break
        }
    }

    /// 获取当前相机点位
    func position() -> Position {
        switch gpuCamera.cameraPosition() {
        case .back: return .back

        case .front: return .front

        default: return .unknown
        }
    }

    /// 翻转相机
    func rotateCamera() {
        var _position: Position = .unknown

        switch position() {
        case .back: _position = .front

        case .front: _position = .back

        default: break
        }

        willRotateCameraBlock?(_position)

        gpuCamera.rotateCamera()

        didRotateCameraBlock?(_position)
    }

    /// 摄像头即将切换
    func setWillRotateCameraBlock(_ block: @escaping AxcBlock.OneParam<Camera.Position>) {
        willRotateCameraBlock = block
    }

    /// 摄像头已经完成切换
    func setDidRotateCameraBlock(_ block: @escaping AxcBlock.OneParam<Camera.Position>) {
        didRotateCameraBlock = block
    }

    /// 设置缩放长焦短焦
    func setZoomFactor(_ factor: CGFloat) {
        guard let camera = gpuCamera.inputCamera else { return }

        var newFactor = factor

        camera.axc.configuration { [weak camera] in

            guard let camera = camera else { return }

            if newFactor > camera.activeFormat.videoMaxZoomFactor {
                newFactor = camera.activeFormat.videoMaxZoomFactor

            } else if newFactor < 1 {
                newFactor = 1
            }

            camera.videoZoomFactor = newFactor
        }
    }

    /// 获取缩放指数
    func zoomFactor() -> CGFloat {
        guard let camera = gpuCamera.inputCamera else { return 0 }

        return camera.videoZoomFactor
    }

    /// 设置对焦点位
    func setFoucsPoint(_ focusPoint: CGPoint) {
        guard let camera = gpuCamera.inputCamera else { return }

        camera.axc.configuration { [weak camera] in

            guard let camera = camera else { return }

            if camera.isFocusModeSupported(.autoFocus) {
                camera.focusPointOfInterest = focusPoint

                camera.focusMode = .autoFocus
            }
        }
    }

    /// 设置为连续自动对焦
    func setContinuousAutoFocus() {
        guard let camera = gpuCamera.inputCamera else { return }

        camera.axc.configuration { [weak camera] in

            guard let camera = camera else { return }

            if camera.isFocusModeSupported(.continuousAutoFocus) {
                camera.focusMode = .continuousAutoFocus
            }
        }
    }

    /// 闪光灯模式
    func setFlashMode(_ flashMode: FlashMode) {
        guard let camera = gpuCamera.inputCamera,

              camera.hasFlash,

              camera.hasTorch else { return }

        camera.axc.configuration { [weak camera] in

            guard let camera = camera else { return }

            switch flashMode {
            case .off:

                camera.torchMode = .off

                camera.flashMode = .off

            case .auto:

                camera.torchMode = .off

                camera.flashMode = .auto

            case .on:

                camera.torchMode = .off

                camera.flashMode = .on

            case .torch:

                camera.torchMode = .on

                camera.flashMode = .off
            }
        }
    }

    /// 是否有手电筒功能
    func hasTorch() -> Bool {
        guard let camera = gpuCamera.inputCamera else { return false }

        return camera.hasTorch
    }

    /// 是否有闪光灯功能
    func hasFlash() -> Bool {
        guard let camera = gpuCamera.inputCamera else { return false }

        return camera.hasFlash
    }

    /// 采集照片
    func collectPhoto(gpuFilter: GPUFilter,

                      block: @escaping AxcBlock.OneParam<UIImage>) {
        guard capturePhotoFinish else { return }

        capturePhotoFinish = false

        gpuCamera.capturePhotoAsImageProcessedUp(toFilter: gpuFilter) { image, _ in

            if let image = image {
                AxcGCD.Main { [weak self] in

                    guard let weakSelf = self else { return }

                    weakSelf.capturePhotoFinish = true

                    block(image)
                }
            }
        }
    }
}
